﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;
using Microsoft.SharePoint.Client;
using FluxJpeg.Core.Encoder;
using System.IO;
using FluxJpeg.Core;
using System.Windows.Browser;

namespace TakeAPicture
{
    public partial class MainPage : UserControl
    {
        #region Properties
        public Guid ListID { get; set; }
        public string ImageSource { get; set; }
        public string HiddenFieldID { get; set; }
        public string WebUrl { get; set; } 
        #endregion

        public MainPage()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            string hiddenValue = HtmlPage.Document.GetElementById(HiddenFieldID).GetAttribute("value");
            if (!String.IsNullOrEmpty(hiddenValue))
                imgPicture.Source = new BitmapImage(new Uri(hiddenValue, UriKind.RelativeOrAbsolute));

            //if (!String.IsNullOrEmpty(hiddenValue))
            //    imgPicture.Source = new BitmapImage(new Uri(String.Format("{0}{1}", WebUrl, hiddenValue), UriKind.RelativeOrAbsolute));
            //else if (!String.IsNullOrEmpty(ImageSource))
            //    imgPicture.Source = new BitmapImage(new Uri(String.Format("{0}{1}", WebUrl, ImageSource), UriKind.RelativeOrAbsolute));
        }

        private void btnTakePicture_Click(object sender, RoutedEventArgs e)
        {
            WebCamControl window = new WebCamControl();
            window.Closed += (s, args) =>
                {
                    WriteableBitmap b = window.Bitmap;
                    imgPicture.Source = b;
                   
                    MemoryStream ms = GetImageStream(b);
                    byte[] data = new byte[ms.Length];
                    ms.Read(data, 0, data.Length);

                    ClientContext context = ClientContext.Current;
                    List list = context.Web.Lists.GetById(ListID);

                    FileCreationInformation info = new FileCreationInformation();
                    info.Content = data;
                    info.Overwrite = false;
                    info.Url = String.Format("{0}.jpg", Guid.NewGuid());
                    ImageSource = info.Url;
                    Microsoft.SharePoint.Client.File f = list.RootFolder.Files.Add(info);
                    context.Load(f);
                    context.ExecuteQueryAsync(new ClientRequestSucceededEventHandler(OnSuccess),
                        new ClientRequestFailedEventHandler(OnFail));                    

                };
            window.Show();
        }

        private void OnSuccess(object sender, ClientRequestSucceededEventArgs args)
        {
            Dispatcher.BeginInvoke(() =>
                {
                    HtmlPage.Document.GetElementById(HiddenFieldID).SetAttribute("value", String.Format("{0}/Lists/TakeAPicture/{1}", WebUrl, ImageSource));
                });
        }

        private void OnFail(object sender, ClientRequestFailedEventArgs args)
        {
            Dispatcher.BeginInvoke(() =>
            {
                MessageBox.Show(args.Message);
            });
        }

        #region Image processing
        public static MemoryStream GetImageStream(WriteableBitmap bitmap)
        {
            byte[][,] raster = ReadRasterInformation(bitmap);
            return EncodeRasterInformationToStream(raster, ColorSpace.RGB);
        }

        public static byte[][,] ReadRasterInformation(WriteableBitmap bitmap)
        {
            if (bitmap != null)
            {
                int width = bitmap.PixelWidth;
                int height = bitmap.PixelHeight;
                int bands = 3;
                byte[][,] raster = new byte[bands][,];

                for (int i = 0; i < bands; i++)
                {
                    raster[i] = new byte[width, height];
                }

                for (int row = 0; row < height; row++)
                {
                    for (int column = 0; column < width; column++)
                    {
                        int pixel = bitmap.Pixels[width * row + column];
                        raster[0][column, row] = (byte)(pixel >> 16);
                        raster[1][column, row] = (byte)(pixel >> 8);
                        raster[2][column, row] = (byte)pixel;
                    }
                }

                return raster;
            }
            return null;
        }

        public static MemoryStream EncodeRasterInformationToStream(byte[][,] raster, ColorSpace colorSpace)
        {
            ColorModel model = new ColorModel { colorspace = ColorSpace.RGB };
            FluxJpeg.Core.Image img = new FluxJpeg.Core.Image(model, raster);

            MemoryStream stream = new MemoryStream();
            FluxJpeg.Core.Encoder.JpegEncoder encoder = new FluxJpeg.Core.Encoder.JpegEncoder(img, 100, stream);
            encoder.Encode();

            stream.Seek(0, SeekOrigin.Begin);

            return stream;
        } 
        #endregion       
    }
}
